package com.woniuxy.project.send.config;

import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.NonNull;

/**
 * 开启消息生产者消息确认：
 * 1、消息到达交换机的确认  setConfirmCallback
 * 2、消息从交换机路由到队列失败的确认
 */
@Configuration
public class RabbitConfiguration {

    /**
     * 创建并配置RabbitMQ消息模板Bean
     *
     * @param connectionFactory 连接工厂，用于建立与RabbitMQ服务器的连接
     * @return RabbitTemplate 配置好的RabbitTemplate实例
     */
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        // 开启消息的强制投递
        rabbitTemplate.setMandatory(true);

        // 消息到达交换机确认
        // 配置消息确认回调，用于监听消息是否成功到达交换机
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("消息数据：" + correlationData);
                System.out.println("应答数据：" + ack);
                if (ack) {
                    System.out.println("消息到达交换机");
                } else {
                    System.out.println("消息未到达交换机，原因是：" + cause);
                    // 网络原因重发 / 消息表中（主键、消息id、消息内容）
                }
            }
        });

        // 消息从交换机路由到队列失败的确认
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            @Override
            public void returnedMessage(@NonNull ReturnedMessage returned) {
                System.out.println("===========================================");
                // 交换机
                System.out.println("returned.getExchange() = " + returned.getExchange());
                // 队列
                System.out.println("returned.getRoutingKey() = " + returned.getRoutingKey());
                // 消息内容
                System.out.println("returned.getMessage() = " + returned.getMessage());
                // 回退编码
                System.out.println("returned.getReplyCode() =" + returned.getReplyCode());
                // 应答内容
                System.out.println("returned.getReplyText() = " + returned.getReplyText());
                System.out.println("===========================================");
            }
        });

        return rabbitTemplate;
    }

}
